bitkeeper revision 1.304.1.5 (3f0bdfabhNAbf77xMA6z5OyrFKHExA)
authorrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>
Wed, 9 Jul 2003 09:26:03 +0000 (09:26 +0000)
committerrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>
Wed, 9 Jul 2003 09:26:03 +0000 (09:26 +0000)
Add VBD create command
Fix parser so that it should hopefully now always print usage instead of throwing unamusing exceptions

.rootkeys
tools/control/src/org/xenoserver/cmdline/Main.java
tools/control/src/org/xenoserver/cmdline/ParseGroup.java
tools/control/src/org/xenoserver/cmdline/ParseVbdCreate.java [new file with mode: 0644]
tools/control/src/org/xenoserver/control/CommandVbdCreate.java [new file with mode: 0644]
tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java [new file with mode: 0644]

index 09528b586d9f6ec65a3a2d2a2ce539f806d86cf9..5ea616d2f1794b5d789849a251930deaab8dea44 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
@@ -30,6 +30,7 @@
 3f05631dswxJX_TpcuG6tBstyHSetg tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java
 3f05631dMY7PMkwSY7zBFelGJ8goVg tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java
 3f05631dYDFXv6mwNFAgz3ta9kShJA tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java
+3f0bdfabfXM4tMbvmV06di5U-5FfqA tools/control/src/org/xenoserver/cmdline/ParseVbdCreate.java
 3f098761TRsbDk9woUM846Q6_F7EmA tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java
 3f099009pmH9MFkRYwP2V1DfsqEwdg tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java
 3f098761zh9WTV6LpRqcet3gqlXdtg tools/control/src/org/xenoserver/cmdline/ParseVdFree.java
@@ -46,6 +47,8 @@
 3f05631ev3UK5FRi5vgR08zDp3OZYw tools/control/src/org/xenoserver/control/CommandPhysicalGrant.java
 3f05631e_G6wzHhEnpihX0pIkEsbMw tools/control/src/org/xenoserver/control/CommandPhysicalList.java
 3f05631eGWxq7bojQbMa-tGxsENIhw tools/control/src/org/xenoserver/control/CommandPhysicalRevoke.java
+3f0bdfab88VYiD26FXCDmmAAGJ8zWA tools/control/src/org/xenoserver/control/CommandVbdCreate.java
+3f0bdfabI14M5_odjCIwQbXCdauReA tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java
 3f098761c5-idlmf9vWEMOlDw0VCHg tools/control/src/org/xenoserver/control/CommandVdCreate.java
 3f0990096KcyQw77qJmjTu941smS8A tools/control/src/org/xenoserver/control/CommandVdDelete.java
 3f0990093VJUL7QjxGigR5GPXf_Fkw tools/control/src/org/xenoserver/control/CommandVdRefresh.java
index 7a3f96af52c1ff9251e83f1cc635fd99799aae07..922a3ca74c08ffbaee634b2dde249bffb5763738 100644 (file)
@@ -1,58 +1,70 @@
 package org.xenoserver.cmdline;
 
 import java.util.LinkedList;
+import java.util.NoSuchElementException;
 
 import org.xenoserver.control.CommandFailedException;
 import org.xenoserver.control.Defaults;
 
+/**
+ * Main class for the command-line xenctl interface.
+ */
 public class Main {
   static final ParseHelp help = new ParseHelp();
-  static final CommandParser domaincommands[] =
+  private static final CommandParser domaincommands[] =
     { new ParseDomainNew(),
       new ParseDomainStart(),
       new ParseDomainStop(),
       new ParseDomainDestroy(),
       new ParseDomainList()
     };
-  static final CommandParser partitioncommands[] =
+  private static final CommandParser partitioncommands[] =
     { new ParsePartitionsAdd(),
       new ParsePartitionsList()
     };
-  static final CommandParser physicalcommands[] =
+  private static final CommandParser physicalcommands[] =
     { new ParsePhysicalGrant(),
       new ParsePhysicalRevoke(),
       new ParsePhysicalList()
     };
-  static final CommandParser vdcommands[] =
+  private static final CommandParser vdcommands[] =
     { new ParseVdCreate(),
       new ParseVdDelete(),
       new ParseVdRefresh(),
       new ParseVdShow(),
       new ParseVdFree()
     };
-  static final CommandParser commands[] =
+  private static final CommandParser vbdcommands[] =
+    { new ParseVbdCreate()
+    };
+  private static final CommandParser commands[] =
     { help,
       new ParseGroup( "domain", domaincommands ),
       new ParseGroup( "partitions", partitioncommands ),
       new ParseGroup( "physical", physicalcommands ),
-      new ParseGroup( "vd", vdcommands )
+      new ParseGroup( "vd", vdcommands ),
+      new ParseGroup( "vbd", vbdcommands )
     };
+  /** The top-level parser. */
   static final CommandParser parser = new ParseGroup( null, commands );
 
   public static void main(String[] args) {
     Defaults d = new Defaults();
     int ec = -1;
     LinkedList arglist = new LinkedList();
-    for ( int i=0; i<args.length; i++ )
+    for ( int i=0; i<args.length; i++ ) {
       arglist.add( args[i] );
+    }
 
     if (args.length == 0) {
-      help.parse(d, arglist);
+      help.parse(null, null);
     } else {
       try
       {
         parser.parse(d, arglist);
         ec = 0;
+      } catch (NoSuchElementException e) {
+          help.parse(null, null);
       } catch (ParseFailedException e) {
         System.err.println( e.getMessage() );
       } catch (CommandFailedException e) {
index cb21eefd8f3f97a2ceea9b0612b3263007a067e3..b57e010ea7f05352dc929ec1e4b5e746d747802a 100644 (file)
@@ -5,69 +5,90 @@ import java.util.LinkedList;
 import org.xenoserver.control.CommandFailedException;
 import org.xenoserver.control.Defaults;
 
+/**
+ * Parses a group of commands; taking the first argument, it searches its
+ * array of commands until it finds a match, and then, removing the matched
+ * argument from the command line, invokes it. This allows hierarchical
+ * parsing.
+ */
 public class ParseGroup extends CommandParser {
-  private final String name;
-  private final CommandParser[] commands;
-  
-  /**
-   * Constructor for ParseGroup.
-   * @param name Name of this group of commands
-   * @param commands Array of commands to include
-   */
-  public ParseGroup(String name, CommandParser[] commands) {
-    this.name = name;
-    this.commands = commands;
-  }
+    /** Name of this group, i.e. the prefix to the command line */
+    private final String name;
+    /** The commands this group will attempt to match its arguments against. */
+    private final CommandParser[] commands;
 
-  public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
-    int i;
-    String c = (String) args.removeFirst();
-    for (i = 0; i < commands.length; i++) {
-      if (commands[i].getName().equals(c)) {
-        if (!args.isEmpty() && args.getFirst().equals("-?")) {
-          commands[i].printHelpText(null);
-        } else {
-          commands[i].parse(d, args);
-        }
-        break;
-      }
+    /**
+     * Constructor for ParseGroup.
+     * @param name Name of this group of commands
+     * @param commands Array of commands to include
+     */
+    public ParseGroup(String name, CommandParser[] commands) {
+        this.name = name;
+        this.commands = commands;
     }
-    if (i == commands.length) {
-      throw new ParseFailedException("Unknown command " + c);
+
+    public void parse(Defaults d, LinkedList args)
+        throws ParseFailedException, CommandFailedException {
+        if (args.isEmpty()) {
+            Main.help.parse(null,null);
+            return;
+        }
+        
+        int i;
+        String c = (String) args.removeFirst();
+        for (i = 0; i < commands.length; i++) {
+            if (commands[i].getName().equals(c)) {
+                if (!args.isEmpty() && args.getFirst().equals("-?")) {
+                    commands[i].printHelpText(null);
+                } else {
+                    commands[i].parse(d, args);
+                }
+                break;
+            }
+        }
+        if (i == commands.length) {
+            throw new ParseFailedException("Unknown command " + c);
+        }
     }
-  }
 
-  public String getName() {
-    return name;
-  }
+    public String getName() {
+        return name;
+    }
 
-  public String getUsage() {
-    return null;
-  }
+    public String getUsage() {
+        return null;
+    }
 
-  public String getHelpText() {
-    return null;
-  }
+    public String getHelpText() {
+        return null;
+    }
 
-  public void printUsage(String prefix) {
-    if ( prefix == null )
-      prefix = name;
-    else
-      prefix += " " + name;
-    for ( int i=0; i<commands.length; i++ )
-      commands[i].printUsage(prefix);
-  }
+    public void printUsage(String prefix) {
+        if (prefix == null) {
+            prefix = name;
+        } else {
+            prefix += " " + name;
+        }
+        for (int i = 0; i < commands.length; i++) {
+            commands[i].printUsage(prefix);
+        }
+    }
 
-  public void printHelpText(LinkedList args) {
-    if ( name != null )
-      System.out.print( name + " " );
-    int i;
-    String c = (String) args.removeFirst();
-    for (i = 0; i < commands.length; i++) {
-      if (commands[i].getName().equals(c)) {
-        commands[i].printHelpText(args);
-        break;
-      }
+    public void printHelpText(LinkedList args) {
+        if (args == null) {
+            Main.help.parse(null,null);
+            return;            
+        }
+        if (name != null) {
+            System.out.print(name + " ");
+        }
+        int i;
+        String c = (String) args.removeFirst();
+        for (i = 0; i < commands.length; i++) {
+            if (commands[i].getName().equals(c)) {
+                commands[i].printHelpText(args);
+                break;
+            }
+        }
     }
-  }
 }
diff --git a/tools/control/src/org/xenoserver/cmdline/ParseVbdCreate.java b/tools/control/src/org/xenoserver/cmdline/ParseVbdCreate.java
new file mode 100644 (file)
index 0000000..bae98b3
--- /dev/null
@@ -0,0 +1,80 @@
+package org.xenoserver.cmdline;
+
+import java.util.LinkedList;
+
+import org.xenoserver.control.CommandFailedException;
+import org.xenoserver.control.CommandVbdCreate;
+import org.xenoserver.control.CommandVbdCreatePhysical;
+import org.xenoserver.control.Defaults;
+import org.xenoserver.control.Mode;
+import org.xenoserver.control.Partition;
+import org.xenoserver.control.PartitionManager;
+import org.xenoserver.control.VirtualDisk;
+import org.xenoserver.control.VirtualDiskManager;
+
+public class ParseVbdCreate extends CommandParser {
+    public void parse(Defaults d, LinkedList args)
+        throws ParseFailedException, CommandFailedException {
+        String vd_key = getStringParameter(args, 'k', "");
+        String partition_name = getStringParameter(args, 'p', "");
+        int domain_id = getIntParameter(args, 'n', 0);
+        int vbd_num = getIntParameter(args, 'v', -1);
+        boolean write = getFlagParameter(args, 'w');
+
+        if (vd_key.equals("") && partition_name.equals("")) {
+            throw new ParseFailedException("Expected -k<key> or -p<partition>");
+        }
+        if (domain_id == 0) {
+            throw new ParseFailedException("Expected -n<domain_id>");
+        }
+        if (vbd_num == -1) {
+            throw new ParseFailedException("Expected -v<vbd_num>");
+        }
+
+        Mode mode;
+        if (write) {
+            mode = Mode.READ_WRITE;
+        } else {
+            mode = Mode.READ_ONLY;
+        }
+
+        loadState();
+        String output;
+        if (vd_key.equals("")) {
+            Partition p = PartitionManager.IT.getPartition(partition_name);
+            if ( p == null ) {
+                throw new CommandFailedException("No partition " + partition_name + " exists" );
+            }
+            
+            output = new CommandVbdCreatePhysical( p, domain_id, vbd_num, mode ).execute();
+        } else {
+            VirtualDisk vd = VirtualDiskManager.IT.getVirtualDisk(vd_key);
+            if (vd == null) {
+                throw new CommandFailedException(
+                    "No virtual disk with key " + vd_key);
+            }
+
+            output =
+                new CommandVbdCreate(vd, domain_id, vbd_num, mode).execute();
+        }
+        if (output != null) {
+            System.out.println(output);
+        }
+        saveState();
+    }
+
+    public String getName() {
+        return "create";
+    }
+
+    public String getUsage() {
+        return "-n<domain_id> {-k<key>|-p<partition} -v<vbd_num> [-w]";
+    }
+
+    public String getHelpText() {
+        return "Create a new virtual block device binding the virtual disk with\n"
+            + "the specified key to the domain and VBD number given. Add -w to\n"
+            + "allow read-write access.";
+    }
+
+}
diff --git a/tools/control/src/org/xenoserver/control/CommandVbdCreate.java b/tools/control/src/org/xenoserver/control/CommandVbdCreate.java
new file mode 100644 (file)
index 0000000..2b7f150
--- /dev/null
@@ -0,0 +1,65 @@
+package org.xenoserver.control;
+
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Create a virtual block device.
+ */
+public class CommandVbdCreate extends Command {
+    /** Virtual disk to map to. */
+    private VirtualDisk vd;
+    /** Domain to create VBD for. */
+    private int domain_id;
+    /** VBD number to use. */
+    private int vbd_num;
+    /** Access mode to grant. */
+    private Mode mode;
+
+    /**
+     * Constructor for CommandVbdCreate.
+     * @param vd VirtualDisk to map to.
+     * @param domain_id Domain to map for.
+     * @param vbd_num VBD number within domain.
+     * @param mode Access mode to grant.
+     */
+    public CommandVbdCreate(
+        VirtualDisk vd,
+        int domain_id,
+        int vbd_num,
+        Mode mode) {
+        this.vd = vd;
+        this.domain_id = domain_id;
+        this.vbd_num = vbd_num;
+        this.mode = mode;
+    }
+
+    /**
+     * @see org.xenoserver.control.Command#execute()
+     */
+    public String execute() throws CommandFailedException {
+        VirtualBlockDevice vbd;
+
+        vbd =
+            VirtualDiskManager.IT.createVirtualBlockDevice(
+                vd,
+                domain_id,
+                vbd_num,
+                mode);
+        String command = vd.dumpForXen(vbd);
+
+        try {
+            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
+            fw.write(command);
+            fw.flush();
+            fw.close();
+        } catch (IOException e) {
+            throw new CommandFailedException("Could not write VBD details to /proc/xeno/dom0/vhd", e);
+        }
+
+        return "Created virtual block device "
+            + vbd_num
+            + " for domain "
+            + domain_id;
+    }
+}
diff --git a/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java b/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java
new file mode 100644 (file)
index 0000000..b804ef2
--- /dev/null
@@ -0,0 +1,66 @@
+package org.xenoserver.control;
+
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Create a virtual block device.
+ */
+public class CommandVbdCreatePhysical extends Command {
+    /** Virtual disk to map to. */
+    private Partition partition;
+    /** Domain to create VBD for. */
+    private int domain_id;
+    /** VBD number to use. */
+    private int vbd_num;
+    /** Access mode to grant. */
+    private Mode mode;
+
+    /**
+     * Constructor for CommandVbdCreate.
+     * @param partition Partition to map to.
+     * @param domain_id Domain to map for.
+     * @param vbd_num VBD number within domain.
+     * @param mode Access mode to grant.
+     */
+    public CommandVbdCreatePhysical(
+        Partition partition,
+        int domain_id,
+        int vbd_num,
+        Mode mode) {
+        this.partition = partition;
+        this.domain_id = domain_id;
+        this.vbd_num = vbd_num;
+        this.mode = mode;
+    }
+
+    /**
+     * @see org.xenoserver.control.Command#execute()
+     */
+    public String execute() throws CommandFailedException {
+        VirtualDisk vd = new VirtualDisk("vbd:"+partition.getName());
+        vd.addPartition(partition,partition.getNumSects());
+
+        VirtualBlockDevice vbd = new VirtualBlockDevice(
+                vd,
+                domain_id,
+                vbd_num,
+                mode);
+
+        String command = vd.dumpForXen(vbd);
+
+        try {
+            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
+            fw.write(command);
+            fw.flush();
+            fw.close();
+        } catch (IOException e) {
+            throw new CommandFailedException("Could not write VBD details to /proc/xeno/dom0/vhd", e);
+        }
+
+        return "Created virtual block device "
+            + vbd_num
+            + " for domain "
+            + domain_id;
+    }
+}